package org.cleverframe.modules.sys.service;

import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.cleverframe.common.service.BaseService;
import org.cleverframe.common.vo.AjaxMessage;
import org.cleverframe.modules.sys.SysBeanNames;
import org.cleverframe.modules.sys.dao.MDictDao;
import org.cleverframe.modules.sys.entity.MDict;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

/**
 * 多级字典Service<br>
 * @author LiZW
 * @version 2015年6月26日 下午4:19:19
 */
@Service(SysBeanNames.MDictService)
public class MDictService extends BaseService
{
    @Autowired
    @Qualifier(SysBeanNames.MDictDao)
    private MDictDao mDictDao;

    /**
     * 查询多级字典，不分页<br>
     * @param param 查询参数
     * @return 多级字典集合
     */
    public List<MDict> findMDictByType(String mdictType, Long id, String uuid)
    {
        return mDictDao.findMDictByType(mdictType, id, uuid);
    }

    /**
     * 获取某一类型的字典数据，排除当前字典以及当前字典的所有下级字典<br>
     */
    public List<MDict> getMDictTreeExcludeOneself(String mdictType, String fullPath)
    {
        return mDictDao.getMDictTreeExcludeOneself(mdictType, fullPath);
    }

    /**
     * 保存字典<br>
     * 新增字典验证：每一个类型的所有字典都是一颗完整的树，字典类型要与父节点一致<br>
     */
    public boolean addMDict(MDict mdict, AjaxMessage message)
    {
        /* ----------------------------------多级字典验证---------------------------------- */
        MDict parentMDict = null;
        if (mdict.isRootMDict() == false)
        {
            parentMDict = mDictDao.getHibernateDao().get(mdict.getParentId());
            if (parentMDict == null)
            {
                message.setMessage("上级字典[ID=" + mdict.getParentId() + "]不存在");
                return false;
            }
            if (parentMDict.getMdictType().equals(mdict.getMdictType()) == false)
            {
                message.setMessage("保存的多级字典类型与其上级字典的字典类型不一致");
                return false;
            }
        }
        
        /* ----------------------------------多级字典保存---------------------------------- */
        if (mdict.isRootMDict())
        {
            mdict.setParentId(-1L);
        }
        mDictDao.getHibernateDao().save(mdict);
        // 更新FullPath，Hibernate自动更新
        if (mdict.isRootMDict())
        {
            mdict.setFullPath(mdict.getId().toString());
        }
        else
        {
            mdict.setFullPath(parentMDict.getFullPath() + MDict.FULL_PATH_SPLIT + mdict.getId());
        }
        return true;
    }

    /**
     * 更新字典<br>
     * 修改parent_id和mdict_type时要保证“字典类型要与父节点一致”<br>
     * 修改mdict_type，必须同时更新所有子节点<br>
     */
    public boolean updateMDict(MDict mdict, AjaxMessage message)
    {
        /* ----------------------------------多级字典验证---------------------------------- */
        MDict oldMDict = mDictDao.getHibernateDao().get(mdict.getId());
        if (oldMDict == null)
        {
            message.setMessage("更新多级字典失败，多级字典[ID=" + mdict.getId() + "]不存在");
            return false;
        }
        MDict parentMDict = null;
        if (mdict.isRootMDict() == false)
        {
            parentMDict = mDictDao.getHibernateDao().get(mdict.getParentId());
            if (parentMDict == null)
            {
                message.setMessage("上级字典[ID=" + mdict.getParentId() + "]不存在");
                return false;
            }
        }
        if (oldMDict.getParentId().equals(mdict.getParentId()))
        {
            // 没有修改父级编号-节点位置不变
            if (!mdict.isRootMDict())
            {
                if (!oldMDict.getMdictType().equals(mdict.getMdictType()))
                {
                    message.setMessage("当前字典的“字典类型”必须要与父字典一致");
                    return false;
                }
            }
        }
        else
        {
            // 修改了父级编号-节点位置发生变化
            if (!mdict.isRootMDict())
            {
                if (!parentMDict.getMdictType().equals(mdict.getMdictType()))
                {
                    message.setMessage("当前字典的“字典类型”必须要与父字典一致");
                    return false;
                }
            }
        }
        /* ----------------------------------更新多级字典---------------------------------- */
        int updateMDictTypeCount = -1;
        if (!oldMDict.getMdictType().equals(mdict.getMdictType()))
        {
            // 修改了mdict_type
            String fullPath = oldMDict.getFullPath() + "%";
            String mdictType = mdict.getMdictType();
            updateMDictTypeCount = mDictDao.updateMDictType(fullPath, mdictType);
        }

        int updateFullPath = -1;
        if (!oldMDict.getParentId().equals(mdict.getParentId()))
        {
            // 修改了父级编号-节点位置发生变化，更新所有子节点的full_path
            String fullPath = oldMDict.getFullPath() + "%";
            String parentFullPath = "";
            if (parentMDict != null)
            {
                parentFullPath = parentMDict.getFullPath();
            }
            int fullPathSubstringBegin = oldMDict.getFullPath().lastIndexOf(MDict.FULL_PATH_SPLIT) + 1;
            if (fullPathSubstringBegin <= 0)
            {
                fullPathSubstringBegin = 1;
            }
            String fullPathSubstring = oldMDict.getFullPath().substring(fullPathSubstringBegin - 1);
            if (!parentFullPath.endsWith(MDict.FULL_PATH_SPLIT + "") && !fullPathSubstring.startsWith(MDict.FULL_PATH_SPLIT + ""))
            {
                // "...-xxx" + "xxx-..."
                parentFullPath = parentFullPath + MDict.FULL_PATH_SPLIT;
            }
            if (parentFullPath.endsWith(MDict.FULL_PATH_SPLIT + "") && fullPathSubstring.startsWith(MDict.FULL_PATH_SPLIT + ""))
            {
                // "...-xxx-" + "-xxx-..."
                parentFullPath = parentFullPath.substring(0, parentFullPath.length() - 1);
            }
            if (StringUtils.isBlank(parentFullPath) && fullPathSubstring.startsWith(MDict.FULL_PATH_SPLIT + ""))
            {
                // "" + "-xxx-..."
                fullPathSubstringBegin = fullPathSubstringBegin + 1;
            }
            updateFullPath = mDictDao.updateFullPath(fullPath, parentFullPath, fullPathSubstringBegin);
        }

        if (updateMDictTypeCount >= 0 && updateFullPath >= 0)
        {
            // 既更新了FullPath又更新了mdict_type，需要保证修改的数量相同
            if (updateMDictTypeCount != updateFullPath)
            {
                throw new RuntimeException("更新多级字典出错！在更新期间可能出现其他人修改，请重试！");
            }
        }

        // 重新计算full_path、mdict_type、parent_id
        if (mdict.isRootMDict())
        {
            mdict.setParentId(-1L);
            mdict.setFullPath(mdict.getId().toString());
        }
        else
        {
            mdict.setMdictType(parentMDict.getMdictType());
            mdict.setFullPath(parentMDict.getFullPath() + MDict.FULL_PATH_SPLIT + mdict.getId());
        }
        mDictDao.getHibernateDao().getSession().evict(oldMDict);
        mDictDao.getHibernateDao().update(mdict);
        return true;
    }

    /**
     * 删除字典，以及其下级字典<br>
     */
    public int deleteMDict(String fullPath)
    {
        return mDictDao.deleteMDict(fullPath);
    }

    /**
     * 查询多级字典所有字典类型<br>
     * @return 所有字典类型集合
     */
    public List<String> findMDictAllType()
    {
        return mDictDao.findMDictAllType();
    }
}
